package com.acme.bankapp.service.bank;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.acme.bankapp.domain.bank.client.Client;

public class BankServer {
	public static final int SERVER_PORT	 = 5678;

	public static final String MESSAGE_END = "end";

	public static final String MESSAGE_BEGIN = "begin";

	public static final String MESSAGE_PRINT_BALANCE = "balance";

	public static final String MESSAGE_PRINT_MAXIMUM = "maximum";

	public static final String MESSAGE_ADD_ACCOUNT = "add";

	public static void startServer(Bank bank) {
		if (bank == null) return;

		ServerSocket providerSocket = null;
		Socket connection = null;
		ObjectOutputStream out = null;
		ObjectInputStream in = null;
		String message = null;

		try {
			providerSocket = new ServerSocket(SERVER_PORT);
			connection = providerSocket.accept();
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			sendMessage(out, MESSAGE_BEGIN);
			while (true) {
				try {
					message = (String) in.readObject();

					if (MESSAGE_PRINT_BALANCE.equals(message)) {
						sendMessage(out, BankService.getMessageBalance(bank));
					} else if (MESSAGE_PRINT_MAXIMUM.equals(message)) {
						sendMessage(out, BankService.getMessageMaximumAmountToWithdraw(bank));
					} else if (MESSAGE_ADD_ACCOUNT.equals(message)) {
						message = (String) in.readObject();

						try {
							Client client = BankDataLoaderService.parseClient(message);
							bank.addClient(client);
							sendMessage(out, "added");
						} catch (Exception exception) {
							sendMessage(out, exception.getMessage());
						}
					}
				} catch (ClassNotFoundException exception) {
					System.out.println("Wrong format message from client");
				}
				if (MESSAGE_END.equals(message)) {
					sendMessage(out, MESSAGE_END);
					break;
				}
			}
		} catch (IOException exception) {

		} finally {
			try {
				if (in != null)
					in.close();
				if (out != null)
					out.close();
				if (connection != null)
					connection.close();
				if (providerSocket != null)
					providerSocket.close();
			} catch (IOException exception) {
				System.out.println("Error close server");
			}
		}
	}

	private static void sendMessage(ObjectOutputStream out, final String message) {
		try {
			out.writeObject(message);
			out.flush();
		} catch (IOException exception) {
			System.out.println("Error when server try send message to client. Msg: " + message);
		}
	}
}
